﻿using NetworkLib;
using PBO.Data;
using PBO.Util;
using PokemonBattle.BattleNetwork;
using System.Collections.Generic;
using System.Drawing;

namespace PBO.Forms.NetworkForm.BattleForm
{
    public class BattleClientForm : BattleForm
    {
        private Dictionary<byte, TeamData> _teams = new Dictionary<byte, TeamData>();
        protected string _serverAddress;

        protected PokemonBattleClient _client;

        public BattleClientForm(string address, string name, TeamData myTeamValue, BattleMode battleMode)
            : this(address, name, myTeamValue, battleMode, 2)
        {
        }

        public BattleClientForm(string address, string name, TeamData myTeamValue, BattleMode battleMode, byte myPosition)
            : base(name, myPosition, myTeamValue, battleMode)
        {
            Load += BattleClientForm_Load;
            //InitializeComponent();

            _serverAddress = address;
            _myTeamData = myTeamValue;
            SetCaption("对战窗口");
        }
        private void BattleClientForm_Load(object sender, System.EventArgs e)
        {
            InitializeClient();
            ConenctServer();
        }

        private void InitializeClient()
        {
            SetProgressText("正在初始化");
            _client = new PokemonBattleClient(_serverAddress);

            _client.OnConnected += OnConnected;
            _client.OnLogoned += OnLogoned;
            _client.OnSetTeam += OnGetTeam;
            _client.OnSetSeed += OnGetSeed;
            _client.OnSetRules += OnGetRules;
            _client.OnSetMove += OnGetMove;
            _client.OnPlayerExit += OnExit;
            _client.OnDisconnected += OnDisconnected;
            _client.OnTie += OnTie;
            _client.OnConnectFail += OnConnectFail;
            _client.OnLogonFailed += OnLogonFail;
            SetProgressText("正在连接");
        }

        protected virtual void ConenctServer()
        {
            _client.Initialize();
            _client.RunThread();
        }

        protected virtual void OnConnected()
        {
            if (_client != null)
            {
                _client.Logon(_identity, _battleMode, ModShare.GetVersionInfo());
            }
        }

        protected virtual void OnLogoned()
        {
            if (_client != null)
            {
                SetProgressText("正在发送数据");
                SetProgress(30);
                ByteSequence bytes = new ByteSequence();
                bytes.Elements.AddRange(_myTeamData.ToBytes());
                _client.SendTeam(_myPosition, _identity, bytes);
                SetProgressText("正在接收数据");
                SetProgress(60);
            }
        }

        protected virtual void OnConnectFail(NetworkException ex)
        {
            OnError("无法连接到主机");
        }
        protected virtual void OnLogonFail(string message)
        {
            OnError(string.Format("无法登录到主机 : {0}", message));
        }

        protected virtual void OnGetTeam(byte position, string identity, ByteSequence team)
        {
            _teams[position] = TeamData.FromBytes(team.Elements.ToArray());
            SetPlayer(position, identity);
        }
        private void OnGetRules(BattleRuleSequence rules)
        {
            SetRules(rules.Elements);
        }
        private void OnGetSeed(int seed)
        {
            SetRandomSeed(seed);
            SetProgressText("正在初始化对战");
            SetProgress(80);

            if (!_teams.ContainsKey(_myPosition))
                _teams[_myPosition] = _myTeamData;
            OnStartBattle();

            SetProgress(100);
            SetProgressText("初始化完毕");
            HideProgress();
        }
        protected virtual void OnStartBattle()
        {
            StartBattle(_teams);
        }

        protected virtual void OnDisconnected()
        {
            logger.AppendText("与主机断开了连接", Color.Red);
        }

        private void OnExit(string identity)
        {
            PlayerExit(identity);
        }
        private void OnTie(string player, TieMessage message)
        {
            GetTie(player, message);
        }
        private void OnGetMove(PlayerMove move)
        {
            SetMove(move);
        }

        protected override void PlayerMoved(PokemonBattle.BattleNetwork.PlayerMove move)
        {
            if (_client != null)
            {
                _client.SendMove(move);
            }
        }
        protected override void SendTieMessage(PokemonBattle.BattleNetwork.TieMessage message)
        {
            if (_client != null)
            {
                _client.Tie(_identity, message);
            }
        }
        protected override void OnBattleEnd()
        {
            base.OnBattleEnd();
            if (_client != null)
            {
                _client.Stop();
                _client = null;
            }
        }

        protected override void OnEscape(System.Windows.Forms.FormClosingEventArgs e)
        {
            base.OnEscape(e);
            if (e.Cancel)
                return;
            if (_client != null)
            {
                _client.Stop();
                _client = null;
            }
        }
    }
}
